package tuling.netty.chatroom;

import io.netty.channel.Channel;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.channel.group.ChannelGroup;
import io.netty.channel.group.DefaultChannelGroup;
import io.netty.util.concurrent.GlobalEventExecutor;

import java.text.SimpleDateFormat;

/**
 * @author RenGaoshuai
 * @date 2023/11/30 13:12
 * @description
 * 类似于群发消息：消息还是发给了服务器，服务器来分发。
 */
public class ChatRoomServerHandler extends SimpleChannelInboundHandler<String> {

    //GlobalEventExecutor.INSTANCE 是全局的事件执行器，是一个单例
    private static ChannelGroup channelGroup = new DefaultChannelGroup(GlobalEventExecutor.INSTANCE);
    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

    /**
     * 有客户端连接了
     * @param ctx
     * @throws Exception
     */
    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        Channel channel = ctx.channel();
        //给这个容器中的所有客户端发送消息
        channelGroup.writeAndFlush("[ 客户端 ]" + channel.remoteAddress() + " 上线了 " + sdf.format(new java.util.Date()) + "\n");
        //再把新上线的客户端存入容器中
        channelGroup.add(channel);
        //服务器输出消息
        System.out.println("[ 服务端 ]" + channel.remoteAddress() + " 客户端上线了 ");
        System.out.println("[ 服务端 ] 在线客户数量" + channelGroup.size() + "人");
    }

    /**
     * 有客户端关闭了
     * @param ctx
     * @throws Exception
     */
    @Override
    public void channelInactive(ChannelHandlerContext ctx) throws Exception {
        Channel channel = ctx.channel();
        //给这个容器中的所有客户端发送消息
        channelGroup.writeAndFlush("[ 客户端 ]" + channel.remoteAddress() + " 下线了 " + sdf.format(new java.util.Date()) + "\n");
        //服务器输出消息
        System.out.println("[ 服务端 ]" + channel.remoteAddress() + " 客户端下线了 ");
        System.out.println("[ 服务端 ] 在线客户数量" + channelGroup.size() + "人");
    }



    /**
     * 读取数据
     * @param channelHandlerContext
     * @param s
     * @throws Exception
     */
    @Override
    protected void channelRead0(ChannelHandlerContext channelHandlerContext, String s) throws Exception {
        Channel currentChannel = channelHandlerContext.channel();

        channelGroup.forEach( q ->{
            if (q == currentChannel){
                //自己
                q.writeAndFlush("[ 自己 ] 发送了消息：" + s + "\n");
            }else{
                //他人
                q.writeAndFlush("[ 客户端 ] 发送了消息：" + s + "\n");
            }
        });

    }


    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        ctx.close();
    }
}
